﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using Common;
using Common.Helpers;
using Common.Interfaces;
using PCSWpfClient.Commands;
using PCSWpfClient.Resources;
using PCSWpfData;





namespace PCSWpfClient.ViewModel
{
    class PriceViewModel : ItemBaseViewModel
    {

        private InstrumentType _instrumentType;
        private Instrument _instrument;
        private PriceSeries _priceSeries;
        private Price _price;
        private Statictics _staticstics;
        private NotifyTaskCompletion<ICollection<Instrument>> _exceptionText;
        private IRepository _repository;
        DelegateCommand _selectedPriceChangedCommand;


        public RangeEnabledObservableCollection<Instrument> InstrumentList { get; private set; }

        public ObservableCollection<Instrument> ShortInstrumentList { get; private set; }
        public ObservableCollection<PriceSeries> PriceSeriesList { get; private set; }
        public ObservableCollection<Price> PriceList { get; private set; }
        public ObservableCollection<Dividend> DividendList { get; private set; }

        public CollectionView InstrumentView { get; private set; }

        public CollectionView PriceView { get; private set; }


        

        public PriceViewModel(IRepository repository)
        {
           
           string _displayName = "Price";
           base.DisplayName = _displayName;
           InstrumentList = new RangeEnabledObservableCollection<Instrument>();
           PriceSeriesList = new ObservableCollection<PriceSeries>();
           PriceList = new ObservableCollection<Price>();
           DividendList = new ObservableCollection<Dividend>();

           _repository = repository;

          

           var taskComplemtion = new NotifyTaskCompletion<ICollection<Instrument>>(
                    repository.GetSelectionCriteriaAsync(InstrumentList));

           ExceptionText = taskComplemtion;

           ShortInstrumentList = new ObservableCollection<Instrument>(repository.GetInstruments().Skip(10));
           
           InstrumentView = GetInstrumentCollectionView(InstrumentList);
           InstrumentView.Filter = OnFilterInstrument;

           PriceView = GetPriceCollectionView(PriceList);
           PriceView.Filter = OnFilterPrice;

           InstrumentView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
           PriceView.SortDescriptions.Add(new SortDescription("ValueAsOf", ListSortDirection.Descending));

           ProcessPrices(InstrumentList);
           CurrentInstrumentType = InstrumentType.Underlyings;

           
         
        }

        private void ProcessPrices(ObservableCollection<Instrument> InstrumentList)
        {
            
            InstrumentList.ToList().ForEach(x =>
                x.PriceSeriesList.ToList().ForEach(y =>
                    { 
                        y.PriceList.ToList().ForEach(z => PriceList.Add(z));
                        y.DividendList.ToList().ForEach(z => DividendList.Add(z));
                    }));
        }

        bool OnFilterInstrument(object item)
        {
            var instrument = (Instrument)item;
            return instrument.InstrumentTypeId == (int)_instrumentType;
        }

        bool OnFilterPrice(object item)
        {
            if (_priceSeries == null)
                return false;
            var price = (Price)item;
            return price.PriceSeriesId == _priceSeries.Id;
        }

        public ICommand SelectedPriceChangedCommand
        {
            get
            {
                if (_selectedPriceChangedCommand == null)
                    _selectedPriceChangedCommand = new DelegateCommand(x => ShowPriceDetails((Price)x));
                return _selectedPriceChangedCommand;
            }
        }

        private void ShowPriceDetails(Price price)
        {
            
        }


        public CollectionView GetInstrumentCollectionView(ObservableCollection<Instrument> instrumentList)
        {
            return (CollectionView)CollectionViewSource.GetDefaultView(instrumentList);
        }

        public CollectionView GetPriceCollectionView(ObservableCollection<Price> priceList)
        {
            return (CollectionView)CollectionViewSource.GetDefaultView(priceList);
        }

        public InstrumentType CurrentInstrumentType
        {
            get { return _instrumentType; }
            set
            {
                if ( value == _instrumentType)
                    return;

                _instrumentType = value;
                

                base.OnPropertyChanged("CurrentInstrumentType");
                InstrumentView.Refresh();
                CurrentInstrument = (Instrument)InstrumentView.CurrentItem;
            }
        }

        private bool _isEnabledComboedit;
        public bool IsEnabledComboEdit
        {
            get
            {
                return _isEnabledComboedit;
            }
            set
            {
                if (value == _isEnabledComboedit)
                    return;
                _isEnabledComboedit = value;

                base.OnPropertyChanged("IsEnabledComboEdit");
            }
        }



        public Instrument CurrentInstrument
        {
            get { return _instrument; }
            set
            {
                if (value == null || value == _instrument)
                    return;

                _instrument = value;

                IsEnabledComboEdit = !(ShortInstrumentList.Any(x => x.Name == _instrument.Name));

                PriceSeriesList.Clear();
                _instrument.PriceSeriesList.ToList().ForEach(PriceSeriesList.Add);
                base.OnPropertyChanged("CurrentInstrument");
                CurrentPriceSeries = PriceSeriesList.FirstOrDefault();
            }
        }

        public PriceSeries CurrentPriceSeries
        {
            get { return _priceSeries; }
            set
            {
                if (value == _priceSeries)
                    return;

                _priceSeries = value;
                PriceView.Refresh();
                if (_priceSeries != null &&_priceSeries.Statistic != null)
                    CurrentStatistics = _priceSeries.Statistic;
                base.OnPropertyChanged("CurrentPriceSeries");
            }
        }

        public Statictics CurrentStatistics
        {
            get { return _staticstics; }
            set
            {
                if (value == _staticstics)
                    return;

                _staticstics = value;

                base.OnPropertyChanged("CurrentStatistics");
            }
        }


        public Price CurrentPrice
        {
            get { return _price; }
            set
            {
                if (value == _price)
                    return;

                _price = value;

                base.OnPropertyChanged("CurrentPrice");
            }
        }


        public NotifyTaskCompletion<ICollection<Instrument>> ExceptionText
        {
            get { return _exceptionText; }
            set
            {
                if (value == _exceptionText)
                    return;

                _exceptionText = value;

                base.OnPropertyChanged("ExceptionText");
            }
        }

        


       
        
    }
}
